/**
 * Navigation component tests
 */

import React from 'react';
import { render, screen, fireEvent } from '@testing-library/react';
import { MemoryRouter } from 'react-router-dom';
import Navigation from '../../src/components/Navigation';

// Mock Antd components
jest.mock('antd', () => ({
  Layout: {
    Header: ({ children }: { children: React.ReactNode }) => <header>{children}</header>,
    Content: ({ children }: { children: React.ReactNode }) => <main>{children}</main>,
    Sider: ({ children }: { children: React.ReactNode }) => <aside>{children}</aside>,
  },
  Menu: {
    Item: ({ children, ...props }: any) => <li {...props}>{children}</li>,
  },
  Button: ({ children, onClick, ...props }: any) => (
    <button onClick={onClick} {...props}>{children}</button>
  ),
  Space: ({ children }: { children: React.ReactNode }) => <div>{children}</div>,
  Dropdown: ({ children, overlay }: { children: React.ReactNode; overlay: React.ReactNode }) => (
    <div>{children}{overlay}</div>
  ),
  Badge: ({ children, count }: { children: React.ReactNode; count?: number }) => (
    <span>{children}{count && `(${count})`}</span>
  ),
  Typography: {
    Title: ({ children }: { children: React.ReactNode }) => <h2>{children}</h2>,
    Text: ({ children }: { children: React.ReactNode }) => <span>{children}</span>,
  },
}));

// Mock React Router
const mockNavigate = jest.fn();
jest.mock('react-router-dom', () => ({
  ...jest.requireActual('react-router-dom'),
  useNavigate: () => mockNavigate,
  useLocation: () => ({
    pathname: '/dashboard',
    search: '',
    hash: '',
    state: null,
  }),
}));

// Mock Ant Design icons
jest.mock('@ant-design/icons', () => ({
  DashboardOutlined: () => <span>Dashboard</span>,
  BarChartOutlined: () => <span>BarChart</span>,
  SearchOutlined: () => <span>Search</span>,
  TeamOutlined: () => <span>Team</span>,
  FolderOutlined: () => <span>Folder</span>,
  SettingOutlined: () => <span>Setting</span>,
  UserOutlined: () => <span>User</span>,
  LogoutOutlined: () => <span>Logout</span>,
}));

describe('Navigation Component', () => {
  const renderNavigation = (title = '', subtitle = '', children?: React.ReactNode) => {
    return render(
      <MemoryRouter>
        <Navigation title={title} subtitle={subtitle}>
          {children}
        </Navigation>
      </MemoryRouter>
    );
  };

  beforeEach(() => {
    jest.clearAllMocks();
  });

  it('renders navigation header correctly', () => {
    renderNavigation('Test Title', 'Test Subtitle');

    expect(screen.getByText('Test Title')).toBeInTheDocument();
    expect(screen.getByText('Test Subtitle')).toBeInTheDocument();
  });

  it('renders without title and subtitle', () => {
    renderNavigation();

    // Should not crash and should render navigation elements
    expect(document.querySelector('header')).toBeInTheDocument();
  });

  it('renders menu items correctly', () => {
    renderNavigation();

    // Check for main navigation items
    expect(screen.getByText('Dashboard')).toBeInTheDocument();
    expect(screen.getByText('Search')).toBeInTheDocument();
    expect(screen.getByText('Team')).toBeInTheDocument();
  });

  it('highlights active menu item based on current location', () => {
    renderNavigation();

    // Since we're mocking useLocation to return '/dashboard',
    // dashboard should be highlighted
    const dashboardItem = screen.getByText('Dashboard');
    expect(dashboardItem.closest('[class*="ant-menu-item-selected"]')).toBeTruthy();
  });

  it('navigates to correct routes when menu items are clicked', () => {
    renderNavigation();

    const searchItem = screen.getByText('Search');
    fireEvent.click(searchItem);

    expect(mockNavigate).toHaveBeenCalledWith('/search');
  });

  it('renders children content', () => {
    const testContent = <div data-testid="test-content">Test Content</div>;
    renderNavigation('Test', 'Subtitle', testContent);

    expect(screen.getByTestId('test-content')).toBeInTheDocument();
    expect(screen.getByText('Test Content')).toBeInTheDocument();
  });

  it('displays user menu when logged in', () => {
    // Mock user in localStorage
    const mockUser = {
      user_id: 'test-user-123',
      email: 'test@example.com',
      name: 'Test User'
    };
    localStorage.setItem('user', JSON.stringify(mockUser));

    renderNavigation();

    expect(screen.getByText('Test User')).toBeInTheDocument();
  });

  it('shows login option when user is not logged in', () => {
    // Clear localStorage
    localStorage.removeItem('user');

    renderNavigation();

    // Should show login option instead of user name
    expect(screen.getByText('Login')).toBeInTheDocument();
  });

  it('handles logout correctly', () => {
    const mockUser = {
      user_id: 'test-user-123',
      email: 'test@example.com',
      name: 'Test User'
    };
    localStorage.setItem('user', JSON.stringify(mockUser));

    renderNavigation();

    // Click on logout
    const logoutButton = screen.getByText('Logout');
    fireEvent.click(logoutButton);

    // Should clear localStorage and navigate to login
    expect(localStorage.getItem('user')).toBeNull();
    expect(mockNavigate).toHaveBeenCalledWith('/login');
  });

  it('displays navigation badge with count when provided', () => {
    renderNavigation();

    // This would require passing props for badge counts
    // Implementation depends on actual component design
    const badgeElement = screen.getByText(/(\d+)/); // Look for numbers in badges
    if (badgeElement) {
      expect(badgeElement).toBeInTheDocument();
    }
  });

  it('is accessible with proper ARIA labels', () => {
    renderNavigation();

    // Check for proper ARIA attributes
    const navigation = document.querySelector('nav') || document.querySelector('[role="navigation"]');
    if (navigation) {
      expect(navigation).toHaveAttribute('role', 'navigation');
    }
  });

  it('handles responsive behavior correctly', () => {
    // Mock different screen sizes
    Object.defineProperty(window, 'innerWidth', {
      writable: true,
      configurable: true,
      value: 768, // Tablet size
    });

    renderNavigation();

    // Should adapt to mobile/tablet layout
    expect(document.querySelector('header')).toBeInTheDocument();
  });

  it('maintains navigation state on route changes', () => {
    renderNavigation();

    // Simulate route change
    fireEvent.click(screen.getByText('Search'));

    // Navigation should still be visible and functional
    expect(screen.getByText('Dashboard')).toBeInTheDocument();
    expect(screen.getByText('Search')).toBeInTheDocument();
  });

  it('handles keyboard navigation', () => {
    renderNavigation();

    const firstMenuItem = screen.getByText('Dashboard');
    firstMenuItem.focus();

    // Tab through menu items
    fireEvent.keyDown(firstMenuItem, { key: 'Tab' });

    // Should be able to navigate with keyboard
    expect(document.activeElement).toBeInstanceOf(HTMLElement);
  });

  it('loads and displays user avatar if available', () => {
    const mockUser = {
      user_id: 'test-user-123',
      email: 'test@example.com',
      name: 'Test User',
      avatar_url: 'https://example.com/avatar.jpg'
    };
    localStorage.setItem('user', JSON.stringify(mockUser));

    renderNavigation();

    // Should show avatar if available
    const avatarElement = document.querySelector('img[src*="avatar"]');
    if (avatarElement) {
      expect(avatarElement).toHaveAttribute('src', 'https://example.com/avatar.jpg');
    }
  });
});